package com.yytek.am.core.runtime;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import com.yytek.am.constants.AkkaConstants;
import com.yytek.am.core.msg.EventRuleClearUpdateMessage;
import com.yytek.am.core.msg.EventRuleGenerateUpdateMessage;
import com.yytek.am.core.msg.EventRuleUpdateMessage;
import com.yytek.am.core.msg.InputDataMessage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 规则管理actor
 */
public class EventManager extends AbstractActor {
    private Map<String, List<ActorRef>> eventKpiActorMap = new HashMap<String, List<ActorRef>>();
    private Map<Long, ActorRef> eventRuleMap = new HashMap<>();
    private List<Map> customRuleList = new ArrayList<Map>();

    public static Props props() {
        return Props.create(EventManager.class, () -> new EventManager());
    }


    public EventManager() {
        //此处可初始化需要特殊处理的一些消息存放到customRuleList用于区分。基于业务需要增加，暂不增加此逻辑。

    }

    @Override
    public Receive createReceive() {
        //数据库更新后更新规则
        return receiveBuilder().match(EventRuleUpdateMessage.class, this::onEventRuleUpdateMessage)
                .match(EventRuleGenerateUpdateMessage.class, this::onEventRuleGenerateUpdateMessage)
                .match(EventRuleClearUpdateMessage.class, this::onEventRuleClearUpdateMessage)

                .match(InputDataMessage.class, this::onInputDataMessage)
                .build();
    }

    /**
     * 更新告警定义
     *
     * @param message
     */
    private void onEventRuleUpdateMessage(EventRuleUpdateMessage message) {
        ActorRef ref = eventRuleMap.get(message.eventRule.getId());
        if (ref == null && message.type != AkkaConstants.EventRuleUpdateType.DELETE) {
            ref = this.getContext().actorOf(EventRuleActor.props(message.eventRule.getRlObjects()));
            eventRuleMap.put(message.eventRule.getId(), ref);
            //通过kpiName缓存规则ruleActor
            List<ActorRef> eventKpiActorList = eventKpiActorMap.get(message.eventRule.getKpiName());
            if(eventKpiActorList == null){
                eventKpiActorList = new ArrayList<>();
            }
            eventKpiActorList.add(ref);
            //放入ruleActor调用缓存
            eventKpiActorMap.put(message.eventRule.getKpiName(),eventKpiActorList);
        }
        if (message.type != AkkaConstants.EventRuleUpdateType.DELETE) {
            ref.tell(message, this.getSelf());
        } else {
            eventRuleMap.remove(message.eventRule.getId());
            eventKpiActorMap.get(message.eventRule.getKpiName()).removeIf(
                    s->(s.equals(eventRuleMap.get(message.eventRule.getId()))));
        }
    }

    /**
     * 更新告警生成规则
     *
     * @param message
     */
    private void onEventRuleGenerateUpdateMessage(EventRuleGenerateUpdateMessage message) {
        ActorRef ref = eventRuleMap.get(message.eventRuleGenerate.getAlarmDefineId());
        if (ref != null) {
            ref.tell(message, this.getSelf());
        }
    }

    /**
     * 更新告警清除规则
     *
     * @param message
     */
    private void onEventRuleClearUpdateMessage(EventRuleClearUpdateMessage message) {
        ActorRef ref = eventRuleMap.get(message.eventRuleClear.getAlarmDefineId());
        if (ref != null) {
            ref.tell(message, this.getSelf());
        }
    }

    /**
     * 告警源输入数据
     * @param message
     */
    private void onInputDataMessage(InputDataMessage message) {
        List<ActorRef> refs = eventKpiActorMap.get(message.inputData.getKpiName());
        if (refs != null) {
            for (ActorRef ref: refs
                 ) {
                ref.tell(message, this.getSelf());
            }
        }
    }

}
